<?php
/*
# ------------------------------------------------------------------------
# JA Job Board Package
# ------------------------------------------------------------------------
# Copyright (C) 2004-2010 JoomlArt.com. All Rights Reserved.
# @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
# Author: JoomlArt.com
# Websites: http://www.joomlart.com - http://www.joomlancers.com.
# ------------------------------------------------------------------------
*/

// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die('Restricted access');

class paypal extends JObject {         
	var $ipn_log;
	var $ipn_log_file;               
	var $ipn_response;                  
	var $ipn_data = array();  
	var $str_ipn_data='';      
	var $params = array();
	var $config;  
   	function __construct($config) {    	  
      $this->ipn_log_file = JPATH_COMPONENT.'/helper/ipn_log.txt';
      $this->ipn_log_file = JPATH::clean($this->ipn_log_file);
      $this->ipn_log = true;
      $this->ipn_response = '';
      $this->config = $config;
   	}
      	
	function geturl($paypal) {
		
		if ($paypal->mode == 0) {
			return "https://www.sandbox.paypal.com/cgi-bin/webscr";
		}elseif ($paypal->mode == 1) {
			return "https://www.paypal.com/cgi-bin/webscr";
		}
	}
		
	function config_form(){
		global $mainframe, $option;
		/* Fill in the config tag below. Note that need not write the form */
		?>			    
	    <tr>
			<td class="key">
				<?php echo JText::_('Merchant ID');?>
				<br />
				<small><?php echo JText::_('your PayPal account PRIMARY email address');?></small>
			</td>
			<td>
				<input type="text" name="paypal[business]" size="55" value="<?php echo $this->config->business; ?>">						
			</td>
	    </tr>
	    <tr>
			<td class="key">
				<?php echo JText::_('PayPal Server host');?>						
			</td>
			<td>
				<select name="paypal[server]">
					  <option value="https://www.paypal.com/cgi-bin/webscr" <?php if ($this->config->server == 'https://www.paypal.com/cgi-bin/webscr' ) { echo " selected='selected' ";}  ?> >PayPal [www.paypal.com]</option>
					  <option value="https://www.sandbox.paypal.com/cgi-bin/webscr" <?php if ($this->config->server == 'https://www.sandbox.paypal.com/cgi-bin/webscr' ) { echo " selected='selected' ";}  ?>>PayPal Sand Box [www.sandbox.paypal.com]</option>
				</select> <br/>
				<small><?php echo JText::_('Note'); ?>: <?php echo JText::_('If you want to test the paypal IPN functions, you can set the host to PayPal\'s sand-box server. Set to www.paypal.com once your website goes live'); ?></small> 
			</td>
	    </tr>	    
	    
	    <tr>
			<td class="key">
				<?php echo JText::_('Paypal Return URL');?>					
			</td>
			<td>
				<input type="text" name="paypal[return]" size="80" value="<?php echo $this->config->return; ?>"/>								<br/>
		  	 	<small><?php echo JText::_('Eg'); ?>: <b><?php echo JRoute::_(JURI::root()."index.php?option=$option&view=japayment&task=payment_return&payment_method=".$this->config->name) ?></b> <br/>
		  	 	<?php echo JText::_(" Note: This URL should also be entered as the 'Return URL' on the 'Website Payment Preferences in your PayPal account")?></small>
			</td>
	    </tr>
	    <tr>
			<td class="key">
				<?php echo JText::_('Paypal Notify URL');?>					
			</td>
			<td>
				<input type="text" name="paypal[notify_url]" size="80" value="<?php echo $this->config->notify_url; ?>"/>								<br/>
		  	 	<small><?php echo JText::_('Eg'); ?>: <b><?php echo JRoute::_(JURI::root()."index.php?option=$option&view=japayment&task=payment_notify&payment_method=".$this->config->name); ?></b> <br/>
		  	 	<?php echo JText::_(" Note: This URL should also be entered as the 'Return notify' on the 'Website Payment Preferences in your PayPal account")?></small>
			</td>
	    </tr>
		<tr>
		  <td class="key">
		  	<?php echo JText::_('Paypal Cancelled URL');?>				  	
		  </td>
		  <td>
		  	 <input type="text" name="paypal[cancel_return]" size="80" value="<?php echo $this->config->cancel_return; ?>">
		  	 <br/>
		  	 <small><?php echo JText::_('Eg'); ?>: <b><?php echo JRoute::_(JURI::root()."index.php?option=$option&view=japayment&layout=payment_cancel&payment_method=".$this->config->name)?></b></small>
		  </td>
		</tr>			
		<tr>
			<td class="key">
				<?php echo JText::_('Paypal IPN URL');?>					
			</td>
			<td>
				<input type="text" name="paypal[paypal_ipn_url]" size="80" value="<?php echo $this->config->paypal_ipn_url; ?>">
				
			</td>
	    </tr>
		<tr>
		  <td class="key">
		  	<?php echo JText::_('Paypal Page Style');?>				  	
		  </td>
		  <td>
		  	 <input type="text" name="paypal[paypal_page_style]" size="80" value="<?php echo $this->config->paypal_page_style; ?>">
		  	 <br/>
		  	 <small><?php echo JText::_("(Your PayPal account's page style. Defined in your paypal account's options.)")?></small>
		  </td>
		</tr>	    	  
		 	
  		<input name="paypal[no_note]" value="1" type="hidden">
  		<input name="paypal[cmd]" value="_xclick" type="hidden">
  		<input name="name" value="paypal" type="hidden">  		  		
		<?php
	}
	
	function more_info(){
		?>
		<fieldset>
			<legend><?php echo JText::_('More info');?></legend>			
						  
			<?php echo JText::_('Important Note for PayPal Subscription: If your user purchases a Subscription or monthly Membership, then at the end of the term <b>PayPal will re-bill them automatically</b> and the job board will re-new the subscription automatically. If your customer wants to cancel the automatic re-billing, then they should log in to their PayPal account and cancel it form there. They can do this at any time. Also, if your customer wants to upgrade or downgrade a subscription, they should log in to their PayPal account and cancel the subscription and then wait until it expires on the job board system. After the subscription expires, they can re-order a bigger or smaller plan. It is recommended that you specify these rules in your terms and conditions and/or the edit your order confirmation email templates with these rules, etc.'); ?>  
			<p >
			  <b>
			  
			  	<?php echo JText::_('Note 1'); ?>
			  </b>: 
			  
			  <?php echo JText::_('If your customer wants to upgrade / downgrade immediately, then ask them to cancel the subscription via their PayPal account and then go to Subscription Reports and click the question next to the \'Completed\' status. There you will see a \'Refund\' button where you can immediately terminate their subscription. Your customer would then be able to create a new order from their job board account.'); ?>
			</p>
			<p >
			  <b>
			  	
			  	<?php echo JText::_('Note 2'); ?>
			  </b>: 
			  
			  <?php echo JText::_('In the event of immediate refunds, then you must refund the transaction in your PayPal account and cancel the subscription there. The subscription status on the job board should change automatically.'); ?>
			</p>
			<p >
			  <b>
			  	
			  	<?php echo JText::_('Note 3'); ?>
			  </b>: 
			  
			  <?php echo JText::_('In some cases, the order may fail to re-bill. PayPal will then attempt to re-bill a few times before giving up. If you want paypal to stop the re-attempts, log in to your PayPal account and cancel the subscription manually.'); ?>
			<p>
			  <b>
			  	
			  	<?php echo JText::_('Note 4'); ?>
			  </b>: 
			  			  
			  <?php echo JText::_('In the job board, there are two products which are subject to the PayPal Subscriptions: <i>Subscription to the resume database</i> and <i>Memberships</i>. Although in the PayPal system both of these are considered as subscriptions, the job board uses two different terms to differentiate the products. Also, memberships plans with a one-off fee do not get sent as PayPal subscriptions, but the usual PayPal payments - so a customer is not rebilled for one-off Membership payments.'); ?>
			</p>	
		</fieldset>	
		<?php
	}		
   
	/**
	* Process notification post from paypal
	*
	*/
	function check_payment(){
		$db	= JFactory::getDBO();
		global $jbconfig, $mainframe;
		
		if($this->validate_ipn()){
			
			$txn_id = $this->ipn_data["txn_id"];
			$amount = $this->ipn_data["mc_gross"];
			$transaction_id = (int)substr($this->ipn_data["item_number"],1);
			
			$prefix = substr($this->ipn_data["custom"], 0, 1);						
			$success=true;
			if($amount<=0)
				return false;
			if($txn_id!=""){
				//Check dulicate transaction
				$sql="SELECT count(*) FROM #__ja_transactions WHERE txn_id='$txn_id'";
				$db->setQuery($sql);
				$total = $db->loadResult();
				if($total){
					return false;
				}else {
					$db->setQuery("SELECT * FROM #__ja_transactions WHERE id = ".(int)$transaction_id.";");
					$ret = $db->loadObject();
					
					//check receiver email
					
					if ((trim($this->ipn_data['business'])!='' && trim($this->ipn_data['business']) != trim($this->config->business)) && (trim($this->ipn_data['business'])=='' && $this->ipn_data['receiver_email']==trim($this->config->business))) {
						JError::raiseWarning(1, JText::_("Your transaction was not properly sent to our Account. Please check again."));
						$ret->txn_id = $txn_id;
						$ret->completed = 0;
						$ret->datas = $this->str_ipn_data;
						$ret->id = $transaction_id;
						
						return $ret;
					}
					//check amount
					
					if ((float)$this->ipn_data['mc_gross'] != (float)$ret->amount) {
						JError::raiseWarning(1, JText::_("The amount you transfer to us is incorrect compared to the invoice. Please check again."));
						$ret->txn_id = $txn_id;
						$ret->completed = 0;
						$ret->datas = $this->str_ipn_data;
						$ret->id = $transaction_id;
						
						return $ret;
					}
					
					//check currency
					if (strtolower(trim($this->ipn_data['mc_currency'])) != strtolower(trim($jbconfig['currency']->get('currency_code')))) {
						JError::raiseError(1, JText::_("The the money is not right. Please check again."));
						$ret->txn_id = $txn_id;
						$ret->completed = 0;
						$ret->datas = $this->str_ipn_data;
						$ret->id = $transaction_id;
						
						return $ret;
					}
					
					//generate return 
					$ret->txn_id = $txn_id;
					if($this->ipn_data['payment_status']=='Completed') $ret->completed = 1;
					if($this->ipn_data['payment_status']=='Pending') $ret->completed = 0;					
					$ret->datas = $this->str_ipn_data;
					$ret->id = $transaction_id;
					
					return $ret;
				}
			}else {
				return false;
			}
		}else {
			return false;
		}
	}
	
	function toParamsString($vars){
		$postipn = "";
		$temp_str_ipn = '';
		foreach ($vars as $ipnkey => $ipnval)
		{
			$this->ipn_data["$ipnkey"] = $ipnval;
			$postipn.='&'.@$ipnkey.'='.urlencode(@$ipnval); 
			if (!in_array($ipnkey,array('view','option','payment_method','task')))
				$temp_str_ipn .= @$ipnkey.'='.urlencode(@$ipnval).'<br /> ';
		} // Notify string
		$this->str_ipn_data = substr($temp_str_ipn,0,strlen($temp_str_ipn)-7);
		return $postipn;
	}
	
	function validate_ipn() {
		
		$postipn = $this->toParamsString($_POST);
		$postipn = 'cmd=_notify-validate'.$postipn;
		$error=0; // No errors let's hope it's going to stays like this!
		// IPN validation mode 1: Live Via PayPal Network
		
		$domain = str_replace(array('/cgi-bin/webscr', 'https://'), array('', ''), $this->config->server);
		$url = "/cgi-bin/webscr";
		
		@set_time_limit(60); // Attempt to double default time limit incase we switch to Get
		// Post back the reconstructed instant payment notification
		$socket = @fsockopen($domain,80,$errno,$errstr,30);
		$header = "POST $url HTTP/1.0\r\n";
		$header.= "User-Agent: PHP/".phpversion()."\r\n";
		$header.= "Referer: ".$_SERVER['HTTP_HOST'].
		$_SERVER['PHP_SELF'].@$_SERVER['QUERY_STRING']."\r\n";
		$header.= "Server: ".$_SERVER['SERVER_SOFTWARE']."\r\n";
		$header.= "Host: ".$domain.":80\r\n";
		$header.= "Content-Type: application/x-www-form-urlencoded\r\n";
		$header.= "Content-Length: ".strlen($postipn)."\r\n";
		$header.= "Accept: */*\r\n\r\n";
		//* Note: "Connection: Close" is not required using HTTP/1.0
		// Problem: Now is this your firewall or your ports?
		if (!$socket && !$error)
		{
			// Switch to a Get request for a last ditch attempt!
			$getrq=1;
			if (phpversion() >= '4.3.0'
			&& function_exists('file_get_contents'))
			{} // Checking for a new function
			else
			{ // No? We'll create it instead
				function file_get_contents($ipnget) {
					$ipnget = @file($ipnget);
					return $ipnget[0];
				}
			}
		
			$response = @file_get_contents('https://'.$domain.':80/cgi-bin/webscr?'.$postipn);
			if (!$response)
			{
				return false;
			}
		}
		else // If no problems have occured then we proceed with the processing
		{
			@fputs ($socket,$header.$postipn."\r\n\r\n"); // Required on some environments
			while (!feof($socket))
			{
				$response = fgets ($socket,1024); 
			}
		}
		
		$response = trim ($response); // Also required on some environments
		return strcmp($response, "VERIFIED")?false:true; //Return true if verified, other return false
  	}
   
	function log_ipn_results($success) {
	  if (!$this->ipn_log) return;
	  $text = '['.date('m/d/Y g:i A').'] - '; 
	  if ($success) $text .= "SUCCESS!\n";
	  	else $text .= 'FAIL: '.$this->last_error."\n"; 
	  $text .= "IPN POST Vars from Paypal:\n";
	  foreach ($this->ipn_data as $key=>$value) {
	     $text .= "$key=$value, ";
	  }
	  $text .= "\nIPN Response from Paypal Server:\n ".$this->ipn_response;
	  $fp=fopen($this->ipn_log_file,'a');
	  fwrite($fp, $text . "\n\n"); 
	  fclose($fp);  // close file
	}
	
	function payment_return() {
		
		$db	= JFactory::getDBO();
		global $jbconfig, $mainframe;
		$ret = new stdClass();
		//Receipt paypal account is not merchant type
		
		if (JRequest::getVar('tx'))
		{
			$postipn = $this->toParamsString($_GET);
			$db	= JFactory::getDBO();
			$txn_id = JRequest::getVar('tx');
			$status = JRequest::getVar('st');
			$amount = JRequest::getVar('amt');
			$currency = JRequest::getVar('cc');
			$item_number = JRequest::getVar('item_number');
			$transaction_id = substr($item_number,1);
			$sql="SELECT count(*) FROM #__ja_transactions WHERE txn_id='$txn_id'";
			$db->setQuery($sql);
			$total = $db->loadResult();
			if($total)
				return true;
			$db->setQuery("SELECT * FROM #__ja_transactions WHERE id = ".(int)$transaction_id.";");
			$ret = $db->loadObject();
			if ($amount!=$ret->amount)
				return false;
			if ($currency!=$ret->currency_code)
				return false;
			$ret->completed = $status=='Completed'?1:0;
			$ret->txn_id = $txn_id;
			$ret->datas = $this->str_ipn_data;						
		}
		else 
		{
			$postipn = $this->toParamsString($_POST);
			if ($this->ipn_data["txn_id"]!=''){
				$status = $this->ipn_data['payment_status'];
				$transaction_id = (int)substr($this->ipn_data["item_number"],1);
				$db->setQuery("SELECT * FROM #__ja_transactions WHERE id = ".(int)$transaction_id.";");
				$ret = $db->loadObject();
				if ($this->ipn_data['mc_gross']!=$ret->amount)
					return false;
				if ($this->ipn_data['mc_currency']!=$ret->currency_code)
					return false;
				$ret->completed = $status=='Completed'?1:0;				
				$ret->txn_id = $this->ipn_data['txn_id'];
				$ret->processed_date = date('Y-m-d H:i:s');
				$ret->datas = $this->str_ipn_data;

				if ($status == 'Completed'){					
					?>
					<div id="Mod18" class="jamod module">
					<div>
					<div>
						<div>						
							<div class="jamod-content" style="overflow: hidden;">
								<?php echo JText::_("Your paypal payment has been completed successfully.").'<br/>'.
								JText::_("You will receive an email with information about the status of your transaction within minutes.").'<br/>'.
								JText::_("If you do not receive the email within 20 minutes, please <b>contact us</b>.").'<br/>' ?>
							</div>
						</div>
					</div>
					</div>
					</div> <?php
				 }
				else{
					JError::raiseWarning(1, JText::_("Your process is not complete because your transaction is in status") .' '. $status);
				}
			}			
		}
		
		return $ret;	
	}
	
	function payment_cancel() {
		JError::raiseNotice(1,JText::_("You have cancelled the paypal payment or the payment was not completed."));
		JError::raiseNotice(1,JText::_("Please feel free to contact us if your expreience was not as it should be."));
	}
	
	function assign_params($vars,$values,$payment)
	{
		
		$vars['item_name'] = $values['item_name'];
		$vars['item_number'] = $values['item_number'];
		$vars['custom'] = $values['custom'];
		$vars['amount'] = $values['amount'];
		$vars['currency_code'] = $values['currency_code'];
		$vars['return'] = $payment->config->return;
		return $vars;
		
	}
	
}
?>